import { isLine } from "../math/Line3d";
import { isPt, Point3d } from "../math/Point3d";
import { Vector2d } from "../math/Vector2d";

export const LineCmp = {
  isVertical(line1, line2) {
    if (!isLine(line1) && !isLine(line2)) return false;
    const vec1 = line1.vec;
    const vec2 = line2.vec;
    if (vec1.model * vec2.model === 0) return false;          // 说明线段退化成点
    else if (vec1.dotProduct(vec2) === 0) return true;        // 夹角的余弦值为0，二者垂直
    return false;
  },
  isParallel(line1, line2) {
    if (!isLine(line1) && !isLine(line2)) return false;
    const vec1 = line1.vec;
    const vec2 = line2.vec;
    let deltaX = line1.endPt.x - line1.startPt.x;
    let deltaY = line1.endPt.y - line1.startPt.y;
    const a1a2 = new Vector2d(deltaX, deltaY);
    if (vec1.model * vec2.model === 0) return false;// 说明线段退化成点
    else if (vec1.$cross(vec2) === 0) { // 夹角的正弦值为 0，二者方向一致，可能平行也可能重合
      if (vec1.$cross(a1a2) !== 0) return true;// 说明四点不共线，排除掉重合的情况，二者平行
      else return false; // 二者重合
    }
    return false;
  },
  // https://www.cnblogs.com/tuyang1129/p/9390376.html
  isIntersect(line1, line2) {
    if (!isLine(line1) && !isLine(line2)) return false;

    const vec1 = line1.vec;
    const vec2 = line2.vec;
    const a = line1.startPt;
    const b = line1.endPt;
    const c = line2.startPt;
    const d = line2.endPt;
    const ac = new Vector2d(a, c);
    const ad = new Vector2d(a, d);
    if (vec1.model * vec2.model === 0) return false; // 说明线段退化成点
    if (vec1.$cross(ac) * vec1.$cross(ad) < 0) return true;
    // 特殊情况1：线段之间的交点是端点
    if (vec1.$cross(ac) * vec1.$cross(ad) === 0) return true;
    // 特殊情况2：两条线段重合
    // 先不处理

    return false;
  },
  // https://www.cnblogs.com/ZQUACM-875180305/p/10149769.html
  getInterPt(line1, line2) {
    if (!isLine(line1) && !isLine(line2)) return -1;
    // b1 = (y2 - y1) * x1 + (x1 - x2) * y1
    const b1 = (line1.endPt.y - line1.startPt.y) * line1.startPt.x
      + (line1.startPt.x - line1.endPt.x) * line1.startPt.y;
    // b2 = (y4 - y3) * x3 + (x3 - x4) * y3
    const b2 = (line2.endPt.y - line2.startPt.y) * line2.startPt.x
      + (line2.startPt.x - line2.endPt.x) * line2.startPt.y;
    // D = (x2 - x1)(y4 - y3) - (x4 - x3)(y2 - y1)
    const D = (line1.endPt.x - line1.startPt.x) * (line2.endPt.y - line2.startPt.y)
      - (line2.endPt.x - line2.startPt.x) * (line1.endPt.y - line1.startPt.y);
    // D1 = b2 * (x2 - x1) - b1 * (x4 - x3)
    const D1 = b2 * (line1.endPt.x - line1.startPt.x) - b1 * (line2.endPt.x - line2.startPt.x);
    // D2 = b2 * (y2 - y1) - b1 * (y4 - y3)
    const D2 = b2 * (line1.endPt.y - line1.startPt.y) - b1 * (line2.endPt.y - line2.startPt.y);
    // x0 = D1 / D   y0 = D2 / D
    return new Point3d(D1 / D, D2 / D);
  },
  distPt(pt1, pt2) {
    if (!isPt(pt1) || !isPt(pt2)) return 0;
    let xx = Math.pow(pt2.x - pt1.x, 2)
    let yy = Math.pow(pt2.y - pt1.y, 2)
    return Math.sqrt(xx + yy)
  }
}